package com.otupia.acs.spring.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.sql.DataSource;
import org.apache.log4j.Logger;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.jdbc.core.ResultSetExtractor;

import com.otupia.acs.entity.UserInfo;

public class UserDaoImpl implements UserDao
{
	private static DataSource dataSource;
	private static JdbcTemplate jdbcTmpl;
	private static SQLPool _SQLPool;

	private static Logger logger = Logger.getLogger(UserDaoImpl.class);

	@Override
	public void setDataSource(DataSource dataSource)
	{
		logger.info("calling function BlogDaoImpl"
				+ "#setDataSource with arguments : [" + dataSource + "]");

		UserDaoImpl.dataSource = dataSource;
		UserDaoImpl.jdbcTmpl = new JdbcTemplate(UserDaoImpl.dataSource);
		logger.info("exiting function BlogDaoImpl"
				+ "#setDataSource with result : [" + "void" + "]");
	}

	private UserInfo getUserFromRs(final ResultSet rs) throws SQLException
	{
		logger.info("calling function UserDaoImpl"
				+ "#getUserFromRs with arguments : [" + rs + "]");

		UserInfo user = new UserInfo();

		user.setId(rs.getLong("id"));
		user.setName(rs.getString("name"));
		user.setNickName(rs.getString("nickName"));
		user.setEmail(rs.getString("email"));
		user.setPassword(rs.getString("password"));
		user.setCustomInfo(rs.getString("customerInfo"));

		logger.info("exiting function UserDaoImpl"
				+ "#getUserFromRs with result : [" + user + "]");
		return user;

	}

	@Override
	public UserInfo findUserByNameAndPwd(final String name, final String pwd)
	{

		logger
				.info("calling function UserDaoImpl"
						+ "#findUserByNameAndPwd with arguments : [" + name
						+ pwd + "]");

		final String findUserByNameAndPwdSQL = "select id,name,nickname,password,email,customerInfo from user where name = ? and password = ?";

		PreparedStatementCreator psc = new PreparedStatementCreator()
		{

			@Override
			public PreparedStatement createPreparedStatement(Connection conn)
					throws SQLException
			{
				return conn.prepareStatement(findUserByNameAndPwdSQL);
			}

		};

		PreparedStatementSetter pss = new PreparedStatementSetter()
		{

			@Override
			public void setValues(PreparedStatement ps) throws SQLException
			{
				ps.setString(1, name);
				ps.setString(2, pwd);
			}

		};

		ResultSetExtractor rse = new ResultSetExtractor()
		{

			@Override
			public Object extractData(ResultSet rs) throws SQLException,
					DataAccessException
			{
				while (rs.next())
				{
					return getUserFromRs(rs);
				}

				return null;
			}

		};

		UserInfo resultUserInfo = (UserInfo) UserDaoImpl.jdbcTmpl.query(psc,
				pss, rse);

		logger.info("exiting function UserDaoImpl"
				+ "#findUserByNameAndPwd with result : [" + resultUserInfo
				+ "]");

		return resultUserInfo;
	}

	@Override
	public void createUser(final UserInfo userInfo)
	{
		logger.info("calling function UserDaoImpl"
				+ "#createUser with arguments : [" + userInfo + "]");

		final String registerSQL = "insert into user(name,password,nickname,email) values(?,?,?,?);";

		final Object[] params = new Object[]
		{ userInfo.getName(), userInfo.getPassword(), userInfo.getNickName(),
				userInfo.getEmail() };

		UserDaoImpl.jdbcTmpl.update(registerSQL, params);

		logger.info("exiting function UserDaoImpl"
				+ "#createUser with result : [" + params + "]");

	}

	@Override
	public void deleteUser(UserInfo userInfo)
	{
		logger.info("calling function UserDaoImpl"
				+ "#deleteUser with arguments : [" + userInfo + "]");

		final String deleteSQL = "delete from user where id = ?";
		final Object[] params = new Object[]
		{ userInfo.getId() };

		UserDaoImpl.jdbcTmpl.update(deleteSQL, params);

		logger.info("exiting function UserDaoImpl"
				+ "#deleteUser with result : [" + params + "]");

	}

	@Override
	public void updateUser(UserInfo userInfo)
	{
		logger.info("calling function UserDaoImpl"
				+ "#updateUser with arguments : [" + userInfo + "]");

		final String updateSQL = "update user set password = ? , nickname=?,email=?,customerinfo=?"
			+ " where id = ?";
		final Object[] params = new Object[]
		{ 
				userInfo.getPassword(),
				userInfo.getNickName(),
				userInfo.getEmail(),
				userInfo.getCustomInfo(),
				userInfo.getId()
		};
		
		UserDaoImpl.jdbcTmpl.update(updateSQL,params);
		
		logger.info("exiting function UserDaoImpl"
				+ "#updateUser with result : [" + "void" + "]");
		
	}

	@Override
	public UserInfo findeUserById(final long id)
	{
		logger.info("calling function UserDaoImpl"
				+ "#findeUserById with arguments : [" + id + "]");
		
		final String findUserById = "select id,name,nickname,password,email,customerInfo from user where id = ?";

		PreparedStatementCreator psc = new PreparedStatementCreator()
		{

			@Override
			public PreparedStatement createPreparedStatement(Connection conn)
					throws SQLException
			{
				return conn.prepareStatement(findUserById);
			}

		};

		PreparedStatementSetter pss = new PreparedStatementSetter()
		{

			@Override
			public void setValues(PreparedStatement ps) throws SQLException
			{
				ps.setLong(1, id);
			}

		};

		ResultSetExtractor rse = new ResultSetExtractor()
		{

			@Override
			public Object extractData(ResultSet rs) throws SQLException,
					DataAccessException
			{
				while (rs.next())
				{
					return getUserFromRs(rs);
				}

				return null;
			}

		};

		UserInfo resultUserInfo = (UserInfo) UserDaoImpl.jdbcTmpl.query(psc,
				pss, rse);
		
		logger.info("exiting function UserDaoImpl"
				+ "#findeUserById with result : [" + resultUserInfo + "]");
		
		return resultUserInfo;
	}

}
